package com.musifind.chat;

import java.io.IOException;
import java.util.Random;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;

import com.fizy.client.controllers.FizyControllers;
import com.fizy.client.objects.Track2;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.musifind.activities.R;
import com.musifind.common.GeneralHelper;
import com.musifind.utils.ImageUtils;
import com.musifind.utils.PlayerUtils;
import com.musifind.utils.SessionManager;
import com.musifind.wsclient.objects.Matching;
import com.musifind.wsclient.objects.User;
import com.musifind.wsclient.service.ListeningService;
import com.musifind.wsclient.service.MatchingService;
import com.musifind.wsclient.service.UserService;

public class ChatActivity extends Activity implements OnCompletionListener, SeekBar.OnSeekBarChangeListener {
	private static final String TAG = "ChatActivity";

	private ChatArrayAdapter chatArrayAdapter;
	private ListView listView;
	private EditText chatText;
	private Button buttonSend;
	private ImageView imgMe, imgOpposite;
	private TextView txtArtistName;
	private TextView txtTrackName;

	GoogleCloudMessaging gcm;
	Intent intent;

	private static Random random;
	private String toUserRegId;
	MessageSender messageSender;
	private String strUserPicture;
	SessionManager session;

	private String trackId;
	private String fromRegId;
	private String fromUserId;
	private String matchingId;
	private String action;

	private String trackURL;
	private String trackName;
	private String artistName;

	private Handler mHandler;
	private MediaPlayer mp;
	private PlayerUtils utils;
	private SeekBar songProgressBar;
	private TextView songCurrentDurationLabel;
	private TextView songTotalDurationLabel;
	private int currentSongIndex = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		StrictMode.setThreadPolicy(policy);
		super.onCreate(savedInstanceState);
		Intent i = getIntent();
		toUserRegId = i.getStringExtra(Config.FROM_REG_ID);
		setContentView(R.layout.activity_chat);

		session = new SessionManager(ChatActivity.this);
		strUserPicture = session.getUserPicture();
		progressDialog = new ProgressDialog(ChatActivity.this);

		imgMe = (ImageView) findViewById(R.id.imgMe);
		imgMe.setImageBitmap(GeneralHelper.roundCornerImage(GeneralHelper.stringToBitmap(strUserPicture), 120));

		// Mediaplayer
		mp = new MediaPlayer();
		utils = new PlayerUtils();
		mHandler = new Handler();

		txtTrackName = (TextView) findViewById(R.id.trackName);
		txtArtistName = (TextView) findViewById(R.id.artistName);
		songProgressBar = (SeekBar) findViewById(R.id.songProgressBar);
		songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel);
		songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel);
		imgOpposite = (ImageView) findViewById(R.id.imgOpposite);

		buttonSend = (Button) findViewById(R.id.buttonSend);
		intent = new Intent(this, GCMNotificationIntentService.class);
		registerReceiver(broadcastReceiver, new IntentFilter("com.musifind.chat.chatmessage"));

		// Listeners
		songProgressBar.setOnSeekBarChangeListener(this); // Important
		mp.setOnCompletionListener(this); // Important

		random = new Random();
		messageSender = new MessageSender();
		listView = (ListView) findViewById(R.id.lstChatPanel);
		gcm = GoogleCloudMessaging.getInstance(getApplicationContext());

		chatArrayAdapter = new ChatArrayAdapter(getApplicationContext(), R.layout.activity_chat_message);
		listView.setAdapter(chatArrayAdapter);

		chatText = (EditText) findViewById(R.id.chatText);
		chatText.setOnKeyListener(new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
					return sendChatMessage();
				}
				return false;
			}
		});
		buttonSend.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				sendChatMessage();
			}
		});

		listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
		listView.setAdapter(chatArrayAdapter);

		chatArrayAdapter.registerDataSetObserver(new DataSetObserver() {
			@Override
			public void onChanged() {
				super.onChanged();
				listView.setSelection(chatArrayAdapter.getCount() - 1);
			}
		});

		bundleDatas();
		if ("S".equals(action)) {
			// senkronizeTo();
			new SenkronizeToAsyncTask().execute();
		} else {
			// senkronizeFrom();
			new SenkronizeFromAsyncTask().execute();
		}

	}

	private ProgressDialog progressDialog = null;

	// void senkronizeTo() {
	// // new Thread(new Runnable() {
	// // @Override
	// // public void run() {
	// new SenkronizeToAsyncTask().execute();
	// // }
	// // }).start();
	// }
	//
	// void senkronizeFrom() {
	// // new Thread(new Runnable() {
	// // @Override
	// // public void run() {
	// new SenkronizeFromAsyncTask().execute();
	// // }
	// // }).start();
	// }

	public class SenkronizeToAsyncTask extends AsyncTask<String, Void, String> {
		@Override
		protected void onPreExecute() {
			progressDialog = new ProgressDialog(ChatActivity.this);
			progressDialog.setTitle("Cevap Bekleniyor");
			progressDialog.setMessage("Lütfen bekleyiniz...");
			progressDialog.setCancelable(false);
			progressDialog.show();
		}

		@Override
		protected String doInBackground(String... params) {
			final MatchingService matchingService = new MatchingService();
			runOnUiThread(new Runnable() {
				public void run() {
					while (true) {
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						Matching matching = matchingService.getMatchingById(new Integer(matchingId));
						if (matching.isFlag()) {
							break;
						}
					}
					init();
				}
			});
			return null;
		}

		@Override
		protected void onPostExecute(String s) {
			progressDialog.dismiss();
		}
	}

	public class SenkronizeFromAsyncTask extends AsyncTask<String, Void, String> {
		@Override
		protected void onPreExecute() {
			progressDialog = new ProgressDialog(ChatActivity.this);
			progressDialog.setTitle("Cevap Gönderiliyor");
			progressDialog.setMessage("Lütfen bekleyiniz...");
			progressDialog.setCancelable(false);
			progressDialog.show();
		}

		@Override
		protected String doInBackground(String... params) {
			runOnUiThread(new Runnable() {
				public void run() {
					MatchingService matchingService = new MatchingService();
					matchingService.updateMatching(new Integer(matchingId));
					init();
				}
			});
			return null;
		}

		@Override
		protected void onPostExecute(String s) {
			progressDialog.dismiss();
		}
	}

	private void init() {
		UserService userService = new UserService();
		User user = userService.getUser(new Integer(fromUserId));
		if (user.getImage() != null && user.getImage().length > 0) {
			imgOpposite.setImageBitmap(GeneralHelper.roundCornerImage(ImageUtils.getBitmap(user.getImage()), 120));
		} else {
			Bitmap defaultIcon = GeneralHelper.drawableToBitmap(getResources().getDrawable(R.drawable.pp_facebook));
			imgOpposite.setImageBitmap(GeneralHelper.roundCornerImage(defaultIcon, 280));
		}

		// Toast.makeText(ChatActivity.this, "Handshake", Toast.LENGTH_LONG).show();

		bundleDatas();
		FizyControllers controllers = new FizyControllers();
		Track2 track = controllers.getTrack(trackId);
		trackName = track.getName();
		artistName = track.getArtist().getName();
		trackURL = track.getSecure_url();

		// GeneralHelper.showToast(getApplicationContext(), "toastMessage");

		// TODO:muzik calınacak

		txtTrackName.setText(trackName);
		txtArtistName.setText(artistName);

		playSong(0);
	}

	public void playSong(int songIndex) {

		bundleDatas();
		FizyControllers controllers = new FizyControllers();
		Track2 track = controllers.getTrack(trackId);
		trackURL = track.getSecure_url();

		try {
			mp.reset();
			// mp.setDataSource(songsList.get(songIndex).get("songPath"));
			mp.setDataSource(trackURL);
			mp.prepare();
			mp.start();

			// setting progress bar values
			songProgressBar.setProgress(0);
			songProgressBar.setMax(100);
			songProgressBar.setClickable(false);

			// Updating progress bar
			updateProgressBar();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void updateProgressBar() {
		mHandler.postDelayed(mUpdateTimeTask, 100);
	}

	private Runnable mUpdateTimeTask = new Runnable() {
		public void run() {
			try {
				long totalDuration = mp.getDuration();
				long currentDuration = mp.getCurrentPosition();

				// Displaying Total Duration time
				songTotalDurationLabel.setText("" + utils.milliSecondsToTimer(totalDuration));
				// Displaying time completed playing
				songCurrentDurationLabel.setText("" + utils.milliSecondsToTimer(currentDuration));

				// Updating progress bar
				int progress = (int) (utils.getProgressPercentage(currentDuration, totalDuration));
				// Log.d("Progress", ""+progress);
				songProgressBar.setProgress(progress);

				// Running this thread after 100 milliseconds
				mHandler.postDelayed(this, 100);
			} catch (Exception e) {
			}
		}
	};

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		mHandler.removeCallbacks(mUpdateTimeTask);
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		mHandler.removeCallbacks(mUpdateTimeTask);
		int totalDuration = mp.getDuration();
		int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);

		// forward or backward to certain seconds
		mp.seekTo(currentPosition);

		// update timer progress again
		updateProgressBar();
	}

	private boolean sendChatMessage() {
		// sending gcm message to the paired device
		Bundle dataBundle = new Bundle();
		dataBundle.putString("ACTION", "CHAT");
		dataBundle.putString("TO_USER_REG_ID", fromRegId);
		dataBundle.putString("CHAT_MESSAGE", chatText.getText().toString());
		messageSender.sendMessage(dataBundle, gcm);

		// updating the current device
		chatArrayAdapter.add(new ChatMessage(false, chatText.getText().toString()));
		chatText.setText("");
		return true;
	}

	private void bundleDatas() {
		Bundle bundle = getIntent().getExtras();
		if (bundle != null) {
			trackId = bundle.getString("trackId");
			fromRegId = bundle.getString("fromRegId");
			fromUserId = bundle.getString("fromUserId");
			matchingId = bundle.getString("mId");
			action = bundle.getString("action");
		}
	}

	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.d(TAG, "onReceive: " + intent.getStringExtra("CHAT_MESSAGE"));
			chatArrayAdapter.add(new ChatMessage(true, intent.getStringExtra("CHAT_MESSAGE")));
		}
	};

	@Override
	public void onCompletion(MediaPlayer mp) {

		ListeningService listeningService = new ListeningService();
		listeningService.stopListening(session.getUserId());
	}

	@Override
	public void onDestroy() {
		// Media playerın kapandığı burada dinleniyor. buraya da offline kaydı atılmalı
		ListeningService listeningService = new ListeningService();
		listeningService.stopListening(session.getUserId());
		super.onDestroy();
		mp.release();
	}
}